package org.papervision3d.core.math ;
import org.papervision3d.Papervision3D;	

/**
 * PLUG-IN MEDIA 2D Vector Class, by Seb Lee-Delisle re-written for Papervision3D as Number2D. 
 *  
 * Version 0.1 10 Feb 2008	
 */
class Number2D 
{
	public static inline var RADTODEG :Float = 180/Math.PI;		
	public static inline var DEGTORAD :Float = Math.PI/180;
	
	public var x:Float; 
	public var y:Float; 
	
	public function new (x:Float = 0, y:Float = 0)
	{
		this.x = x; 
		this.y = y;   
	}
	
 
	public function toString():String
	{
		var x:Float = Math.round (this.x * 1000) / 1000;
		var y:Float = Math.round (this.y * 1000) / 1000;
		return "[" + x + ", " + y + "]";
	}
	
	public function clone():Number2D
	{
		return new Number2D(this.x, this.y);
	}
	
	public function copyTo(v:Number2D):Void
	{
		v.x = this.x;
		v.y = this.y;
	}
	public function copyFrom(v:Number2D):Void
	{
		this.x = v.x;
		this.y = v.y;
	}	
	
	public var modulo(get_modulo, null):Float;
	private function get_modulo():Float 
	{
		return Math.sqrt((x*x)+(y*y));
	}
	
	public function normalise():Void 
	{
		var m:Float = this.modulo;
		
		this.x = this.x/m;
		this.y = this.y/m;

		
	}
	
	public function reverse():Void 
	{
		this.x = -this.x;
		this.y = -this.y;
	}
	
	public static function add(v:Number2D, w:Number2D):Number2D {
		
		return new Number2D( v.x+w.x, v.y+w.y);

	}
	public static function subtract(v:Number2D, w:Number2D):Number2D {
		
		return new Number2D( v.x-w.x, v.y-w.y);

	}	
	public function plusEq(v:Number2D) :Void
	{
		x+=v.x; 
		y+=v.y; 
		
	}
	public function minusEq(v:Number2D) :Void
	{
		x-=v.x; 
		y-=v.y; 
		
	}
	
	public function divideEq(d :Float) :Void
	{
		x/=d; 
		y/=d; 
	}
	public function multiplyEq(d :Float) :Void
	{
		x*=d; 
		y*=d; 
	}
	
	
	public static function multiplyScalar(v:Number2D, n:Float) :Number2D
	{
		return new Number2D
		(
			v.x*n,
			v.y*n
		);
		
	}


	
	public static function dot(v:Number2D, w:Number2D):Float
	{
		return v.x * w.x + v.y * w.y ;
	}
	
	
	public function angle():Float
	{
		
		if(Papervision3D.useDEGREES)
			return ( RADTODEG*(Math.atan2(y,x)));
		else 
			return (Math.atan2(y,x));
		

	}
	
	

	public function rotate(angle:Float) :Void{
		if(Papervision3D.useDEGREES) angle*=DEGTORAD;
		var cosRY:Float = Math.cos(angle);
		var sinRY:Float = Math.sin(angle);
		var temp:Number2D;

		temp = clone();
		
		
		this.x= (temp.x*cosRY)-(temp.y*sinRY);
		this.y= (temp.x*sinRY)+(temp.y*cosRY);
		
		
	}	
	
	
	public function reset(x:Float = 0, y:Float = 0) :Void
	{
		
		this.x = x;
		this.y = y;

	}

	// ______________________________________________________________________
	
	/**
	 * Super fast modulo(length, magnitude) comparisons.
	 * 
	 *  
	 */
	 
	public function isModuloLessThan(v:Float):Bool
	{
			
		return (moduloSquared<(v*v)); 
		
	}
	
	public function isModuloGreaterThan(v:Float):Bool
	{
			
		return (moduloSquared>(v*v)); 
		
	}
	public function isModuloEqualTo(v:Float):Bool
	{
			
		return (moduloSquared==(v*v)); 
		
	}
		
	public var moduloSquared(get_moduloSquared, null):Float;
	public function get_moduloSquared():Float
	{
		return ( this.x*this.x + this.y*this.y );
	}
	

}